﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Collections.Specialized;
using Newtonsoft.Json.Linq;
using System.Web;
using Wise.Util.Queryable;

namespace Wise.Util
{




    /// <summary>
    /// 查询信息/查询参数集合
    /// 字段使用-前缀，表示模糊匹配 如（-Asset_Name）
    /// 字段以＞、》、》＝、＞＝开头，表示字段值大于参数值
    /// 字段以《、＜、＜＝、《＝开头，表示字段值小于参数值
    /// 字段以!开头，表示字段值不在对应序列内
    /// 字段以@开头，表示字段值在对应序列内
    /// 当存在大小比较就不再作为模糊查找
    /// </summary>
    [Serializable]
    [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
    public class MyQuery : _Entity
        , IEnumerable<_Parameter>
        , IDictionary<string, _Parameter>
        , IDictionary
    {
        public static MyQuery GET_DEFAULT()
        {
            return new MyQuery();
        }

        #region IEnumerable And Contruct

        /// <summary>
        /// 以与关系创建查询参数组
        /// </summary>
        public MyQuery()
        {
            IsAndRelation = true;
        }

        /// <summary>
        /// 使用自定义关系创建查询参数组
        /// </summary>
        /// <param name="_IsAndRelation"></param>
        public MyQuery(bool _IsAndRelation)
        {
            IsAndRelation = _IsAndRelation;
        }

        /// <summary>
        /// 使用JsonHelper字符串实例化
        /// </summary>
        /// <param name="jsonString"></param>
        public MyQuery(string jsonString)
        {
            var json = JsonHelper.JsonToJObject(jsonString);
            var lst = json.Children();
            foreach (var token in lst)
            {
                if (token.Type == JTokenType.Property)
                {
                    var prop = (JProperty)token;
                    if (string.IsNullOrEmpty(prop.Name))
                    {
                        this.AddOrSet(string.Empty, prop.Value.ToString().Trim());
                    }
                    else
                    {
                        this.AddOrSet(prop.Name.Trim(), prop.Value.ToString().Trim());
                    }
                }
                else if (token.Type == JTokenType.Object)
                {
                    var json1 = (JObject)token;
                    foreach (JProperty prop in json1.Children())
                    {
                        //todo:[不重要]子查询 
                        if (string.IsNullOrEmpty(prop.Name))
                        {
                            this.AddOrSet(string.Empty, prop.Value.ToString().Trim());

                        }
                        else
                        {
                            this.AddOrSet(prop.Name.Trim(), prop.Value.ToString().Trim());
                        }
                    }
                }
            }
        }

        public static MyQuery CreateFromJson(string jsonString)
        {
            return new MyQuery(jsonString);
        }

        /// <summary>
        /// 使用网络地址创建查询
        /// 需要在传入前解码（查询字符串通常会使用Url加码）
        /// ams-start:///?action=designa56a73a9-95b2-4902-b67e-7061060312a4￥ReportId=￥ServiceAddress=http%3a%2f%2fwxj.ams%3a80%2fWXJServices%2fClientService.ashx￥Query=
        /// </summary>
        /// <returns></returns>
        public static MyQuery CreateFromUrl(string requestSearch)
        {
            if (string.IsNullOrEmpty(requestSearch))
            {
                return MyQuery.GET_DEFAULT();
            }
            int idxQ = requestSearch.IndexOf("?");
            string left = requestSearch.Substring(idxQ + 1, requestSearch.Length - idxQ - 1);
            MyQuery q = MyQuery.GET_DEFAULT();
            left.Split('&').Select(x =>
            {
                int idxE = x.IndexOf('=');
                return new string[] {
                    x.Substring(0, idxE)
                    , idxE == x.Length - 1 ? "" : x.Substring(idxE + 1, x.Length - idxE - 1) };
            }).ToList().ForEach(x =>
            {
                string k = x[0];
                if (string.IsNullOrEmpty(k))
                    return;
                if (k.StartsWith("%20") || k.EndsWith("%20"))
                {
                    k = HttpUtility.UrlDecode(k).Trim();
                }
                string v = x[1];
                q[k].Value = v;
            });
            return q;
        }

        public MyQuery Copy()
        {
            var rs = new MyQuery();
            var keys = _Parameters.Keys.ToList();
            for (int i = 0; i < keys.Count; i++)
            {
                var key = keys[i];
                rs._Parameters.Add(key, _Parameters[key]);
            }
            return rs;
        }

        /// <summary>
        /// 使用请求信息获取查询条件
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public static MyQuery CreateFromRequest(params NameValueCollection[] Query)
        {
            MyQuery query = MyQuery.GET_DEFAULT();
            foreach (NameValueCollection request in Query)
            {
                if (request == null)
                    continue;
                var keys = request.AllKeys.ToList();
                foreach (string k1 in keys)
                {
                    if (string.IsNullOrEmpty(k1))
                        continue;
                    string k = k1.Trim(), v = request[k1];
                    if (k.StartsWith("%20") || k.EndsWith("%20"))
                    {
                        k = HttpUtility.UrlDecode(k).Trim();
                    }
                    //if (_IsBadParameter.IsMatch(k))
                    {
                        if (string.Equals(k, "pageIndex", StringComparison.CurrentCultureIgnoreCase)
                            || string.Equals(k, "PagerIndex", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerIndex = NullHelper.Parse<int>(v);
                            continue;
                        }
                        else if (string.Equals(k, "pageSize", StringComparison.CurrentCultureIgnoreCase)
                            || string.Equals(k, "PagerSize", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerSize = NullHelper.Parse<int>(v);
                            continue;
                        }
                        else if (string.Equals(k, "pageOrderBy", StringComparison.CurrentCultureIgnoreCase)
                           || string.Equals(k, "PagerOrderBy", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerOrderBy = v;
                            continue;
                        }
                        //continue;
                    }
                    query.AddOrSet(k, v);
                }
            }
            return query;
        }

        public static MyQuery CreateFromDictionary(params Dictionary<string, string>[] Query)
        {
            MyQuery query = MyQuery.GET_DEFAULT();
            foreach (Dictionary<string, string> request in Query)
            {
                var keys = request.Keys.ToList();
                foreach (string k1 in keys)
                {
                    if (string.IsNullOrEmpty(k1))
                        continue;
                    string k = k1.Trim(), v = request[k1];
                    if (k.StartsWith("%20") || k.EndsWith("%20"))
                    {
                        k = HttpUtility.UrlDecode(k).Trim();
                    }
                    //if (_IsBadParameter.IsMatch(k))
                    {
                        if (string.Equals(k, "pageIndex", StringComparison.CurrentCultureIgnoreCase)
                            || string.Equals(k, "PagerIndex", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerIndex = NullHelper.Parse<int>(v);
                            continue;
                        }
                        else if (string.Equals(k, "pageSize", StringComparison.CurrentCultureIgnoreCase)
                            || string.Equals(k, "PagerSize", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerSize = NullHelper.Parse<int>(v);
                            continue;
                        }
                        else if (string.Equals(k, "pageOrderBy", StringComparison.CurrentCultureIgnoreCase)
                           || string.Equals(k, "PagerOrderBy", StringComparison.CurrentCultureIgnoreCase))
                        {
                            query.PagerOrderBy = v;
                            continue;
                        }
                        //continue;
                    }
                    query.AddOrSet(k, v);
                }
            }
            return query;
        }

        public bool IsAndRelation
        {
            get;
            set;
        }

        [NonSerialized]
        internal readonly _WeekDictionary<string, _Parameter> _Parameters = new _WeekDictionary<string, _Parameter>();


        protected _Parameter CreateOrSet(string key, Object value)
        {
            key = key.Replace(">", "》").Replace("<", "《");
            _Parameter para = _Parameters.GetOrCreate(key, CreateParameter);
            para.Field = key;
            para.Value = value;
            return para;
        }

        protected _Parameter GetOrCreate(string key)
        {
            key = key.Replace(">", "》").Replace("<", "《");
            _Parameter para = _Parameters.GetOrCreate(key, CreateParameter);
            para.Field = key;
            return para;
        }

        private _Parameter CreateParameter()
        {
            return new _Parameter(this);
        }

        /// <summary>
        /// 检测包含字段,且该字段不为空
        /// </summary>
        /// <returns></returns>
        public bool ContainsField(string fieldName, bool ignoreCase = false)
        {
            var list = GetParameterWithOperator(fieldName, ignoreCase);
            for (int i = 0; i < list.Count; i++)
            {
                string key = list[i];
                var item = _Parameters[key];
                if (item.IsNotNull)
                    return true;
            }
            return false;
        }

        /// <summary>
        ///
        /// </summary>
        public int Count
        {
            get
            {
                return _Parameters.Count(x => x.Value.IsNotNull);
            }
        }

        /// <summary>
        ///
        /// </summary>
        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }
        private string _ToString = null;
        /// <summary>
        /// JSON字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            if (_ToString == null)
                _ToString = string.Concat("["
                , string.Join(",", _Parameters.Select(x => x.Value.ToString()).ToArray())
                , "]");
            return _ToString;
        }

        /// <summary>
        /// 增或改
        /// 字段各单词间使用下划线分隔，表示模糊匹配
        /// 字段各单词间无分隔符，表示精确匹配
        /// 字段以>开头，表示字段值大于参数值
        /// 以此类推，支持大于、大于等于、小于、小于等于
        /// 当存在大小比较就不再作为模糊查找
        /// </summary>
        public void AddOrSet(string field, Object value)
        {
            if (base.OnPropertyChanged(field))
            {
                if (string.IsNullOrEmpty(field))
                {
                    _Parameters.AddOrSet(string.Empty, new _Parameter(this, string.Empty, value));
                }
                else
                {
                    _Parameters.AddOrSet(field.Trim(), new _Parameter(this, field, value));
                }
                base.SendPropertyChanged(field);
            }
        }

        /// <summary>
        /// 删除所有以指定字段结尾且可能带一位操作符的字段
        /// 操作符：-、&gt;、&lt;、[等
        /// </summary>
        public void TryRemove(string field, bool ignoreCase = false)
        {
            var toRemove = GetParameterWithOperator(field, ignoreCase);
            foreach (string key in toRemove)
            {
                _Parameters.TryRemove(key);
            }
        }

        /// <summary>
        /// 获取可能匹配的参数列表
        /// </summary>
        /// <param name="field"></param>
        /// <param name="ignoreCase"></param>
        /// <returns></returns>
        public List<string> GetParameterWithOperator(string field, bool ignoreCase)
        {
            field = field.Trim();
            List<string> keys = new List<string>(_Parameters.Keys);
            List<string> res = new List<string>();

            if (ignoreCase)
            {
                for (int i = 0; i < keys.Count; i++)
                {
                    var x = keys[i];
                    if (x != null)
                    {
                        if (x.EndsWith(field, StringComparison.CurrentCultureIgnoreCase) && x.Length - field.Length <= 1)
                        {
                            res.Add(x);
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < keys.Count; i++)
                {
                    var x = keys[i];
                    if (x != null)
                    {
                        if (x.EndsWith(field) && x.Length - field.Length <= 1)
                        {
                            res.Add(x);
                        }
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// 清空列表 清理除内存设置项外的参数。
        /// 如果要清除所有参数，请重新实例化
        /// </summary>
        public void Clear()
        {
            _Parameters.Clear();
        }

        /// <summary>
        /// 清空列表
        /// 清理所有查询条件。
        /// 但是，不清理下滑线开头的参数（它们作为配置项）及分页信息
        /// </summary>
        public void ClearNormalConditional()
        {
            var toRemove = _Parameters
                .Where(x => !x.Key.StartsWith("_") && !x.Key.StartsWith("Pager"))
                .Select(x => x.Key)
                .ToList();
            foreach (string k in toRemove)
            {
                _Parameters.Remove(k);
            }
        }

        /// <summary>
        /// 增、改
        /// </summary>
        /// <param name="item"></param>
        public void Add(_Parameter item)
        {
            _Parameters.AddOrSet(item.Field, item);
        }

        /// <summary>
        /// 包含
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(_Parameter item)
        {
            return _Parameters.ContainsValue(item);
        }

        /// <summary>
        /// 复制到
        /// </summary>
        /// <param name="array"></param>
        /// <param name="arrayIndex"></param>
        public void CopyTo(_Parameter[] array, int arrayIndex)
        {
            _Parameters.Values.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Remove(_Parameter item)
        {
            if (Contains(item))
            {
                if (Monitor.TryEnter(_Parameters._Locker))
                {
                    try
                    {
                        foreach (var kv in _Parameters)
                        {
                            if (kv.Value == item)
                            {
                                if (base.OnPropertyChanged(kv.Key))
                                {
                                    _Parameters.Remove(kv.Key);
                                    base.SendPropertyChanged(kv.Key);
                                }
                                return true;
                            }
                        }
                    }
                    catch //(Exception exp)
                    {
                        //LoggerHelper.Log(exp, Loggers.LoggerType.THREAD);
                    }
                    finally
                    {
                        Monitor.Exit(_Parameters._Locker);
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 枚举
        /// </summary>
        /// <returns></returns>
        public IEnumerator<_Parameter> GetEnumerator()
        {
            return _Parameters.Select(x => x.Value)
                .Where(x => x != null)
                .ToList().GetEnumerator();
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return _Parameters.Values
                .Where(x => x != null).GetEnumerator();
        }

        /// <summary>
        /// 获取参数，会匹配带运算符的参数,忽略大写小
        /// </summary>
        /// <param name="indexer"></param>
        /// <returns></returns>
        public _Parameter this[string indexer]
        {
            get
            {
                if (string.IsNullOrEmpty(indexer))
                    indexer = string.Empty;
                else
                    indexer = indexer.Trim();
                var idx = GetParameterWithOperator(indexer, true);
                if (idx.Count > 0)
                {
                    string key = idx.OrderBy(x => x.Length).FirstOrDefault();
                    return _Parameters[key];
                }
                else
                {
                    var val = new _Parameter(this, indexer);
                    _Parameters.Add(indexer, val);
                    return val;
                }
            }
        }

        #endregion

        protected override void OnModified()
        {
            this._ToString = null;
            base.OnModified();
        }

        #region 视图
        /// <summary>
        /// 视图名称
        /// 真实存在的视图名称，不能填写查询语句
        /// </summary>
        public string _DataViewName
        {
            get
            {
                _Parameter para = GetOrCreate("_DataViewName");
                return para.StringValue;
            }
            set
            {
                CreateOrSet("_DataViewName", value);
            }
        }

        /// <summary>
        /// 查询字段
        /// </summary>
        public string _Selector
        {
            get
            {
                _Parameter para = GetOrCreate("_Selector");
                return para.StringValue;
            }
            set
            {
                CreateOrSet("_Selector", value);
            }
        }


        /// <summary>
        /// 主键名称,不能使用方括号包裹,自动转小写
        /// </summary>
        public string _PrimaryKeyName
        {
            get
            {
                _Parameter para = GetOrCreate("_PrimaryKeyName");
                if (para.IsNull)
                    para.Value = "Id";
                return para.StringValue;
            }
            set
            {
                CreateOrSet("_PrimaryKeyName", string.IsNullOrEmpty(value) ? "" : value.ToLower());
            }
        }
        #endregion

        #region 分页
        public const int DEFAULT_PAGER_SIZE = 10;
        /// <summary>
        /// 数据分页大小
        /// </summary>
        public int PagerSize
        {
            get
            {
                _Parameter para = GetOrCreate("PagerSize");
                if (para.IsNull)
                {
                    para.Value = DEFAULT_PAGER_SIZE;
                }
                return para.IntValue;
            }
            set
            {
                CreateOrSet("PagerSize", value);
            }
        }
        //public static int? _Current_Thread_PagerSize
        //{
        //    get
        //    {
        //        return ThreadCache.Get<int?>("PagerSize");
        //    }
        //    set
        //    {
        //        ThreadCache.Set("PagerSize", value);
        //    }
        //}

        public const int DEFAULT_PAGER_INDEX = 1;
        /// <summary>
        /// 数据分页大小
        /// </summary>
        public int PagerIndex
        {
            get
            {
                _Parameter para = GetOrCreate("PagerIndex");
                return para.IntValue;
            }
            set
            {
                CreateOrSet("PagerIndex", value);
            }
        }

        private int _PagerAllRecordsCount = 0;

        /// <summary>
        /// 数据分页所有记录数
        /// </summary>
        public int PagerAllRecordsCount
        {
            get
            {
                return _PagerAllRecordsCount;
            }
            set
            {
                _PagerAllRecordsCount = value;
            }
        }

        /// <summary>
        /// 数据分页页面大小，计算属性
        /// </summary>
        public int PagerPageCount
        {
            get
            {
                if (PagerSize <= 0)
                {
                    return 0;
                }
                return (int)Math.Ceiling(PagerAllRecordsCount / (float)PagerSize);
            }
            set
            {
                //仅为Xml序列化而留
            }
        }

        private bool _HasPager = true;

        /// <summary>
        /// 有分页信息，计算属性
        /// </summary>
        public bool HasPager
        {
            get
            {
                return _HasPager && PagerSize > 0;
            }
            set
            {
                //仅为Xml序列化而留
            }
        }

        /// <summary>
        /// 排序字段
        /// 半计算字段
        /// 支持多列排序，如 Id asc,CreatedOnDate desc,Name
        /// 默认降序排列
        /// </summary>
        public string PagerOrderBy
        {
            get
            {
                _Parameter para = GetOrCreate("PagerOrderBy");
                if (para.IsNull)
                {
                    return null;
                }
                return para.StringValue;
            }
            set
            {
                string goodValue = value;
                if (!string.IsNullOrEmpty(goodValue))
                {
                    _OrderByExpresses = _GetOrderByExpresses(goodValue);
                    List<string> str = new List<string>(_OrderByExpresses.Count);
                    foreach (Tuple<string, Boolean> kv in _OrderByExpresses)
                    {
                        if (kv.Item2)
                        {
                            str.Add(string.Format("{0} ASC", kv.Item1));
                        }
                        else
                        {
                            str.Add(string.Format("{0} DESC", kv.Item1));
                        }
                    }
                    goodValue = string.Join(",", str);
                }
                CreateOrSet("PagerOrderBy", goodValue);
            }
        }


        private static List<Tuple<string, Boolean>> _GetOrderByExpresses(string orderBy)
        {
            List<Tuple<string, Boolean>> _GetOrderByExpresses = new List<Tuple<string, bool>>();
            if (!string.IsNullOrEmpty(orderBy))
            {
                string[] array = orderBy.Split(',');
                for (int i = 0; i < array.Length; i++)
                {
                    string o = array[i].Trim();
                    string[] s = o.Split(' ');
                    if (s.Length > 1)
                    {
                        _GetOrderByExpresses.Add(new Tuple<string, bool>(s[0], string.Equals("ASC", s[1], StringComparison.CurrentCultureIgnoreCase)));
                    }
                    else
                    {
                        _GetOrderByExpresses.Add(new Tuple<string, bool>(s[0], false));
                    }
                }
            }
            return _GetOrderByExpresses;
        }

        private List<Tuple<string, Boolean>> _OrderByExpresses = null;


        /// <summary>
        /// 清除分页数据
        /// </summary>
        public void RemovePagerInfo()
        {
            _HasPager = false;
            _Parameters.TryRemove("PagerSize");
            _Parameters.TryRemove("PagerIndex");
            //var keys = _Parameters.Keys.ToList();
            //foreach (string k in keys)
            //{
            //    if (k.StartsWith("Pager"))
            //    {
            //        _Parameters.Remove(k);
            //    }
            //}
        }

        #endregion

        #region 日期



        public DateTime? MinCreatedOnDate
        {
            get
            {
                _Parameter para = GetOrCreate("》=CreatedOnDate");
                return para.IsNull ? null : (DateTime?)para.GetValue<DateTime>();
            }
            set
            {
                CreateOrSet("》=CreatedOnDate", value);
            }
        }

        public DateTime? MaxCreatedOnDate
        {
            get
            {
                _Parameter para = GetOrCreate("《=CreatedOnDate");
                return para.IsNull ? null : (DateTime?)para.GetValue<DateTime>();
            }
            set
            {
                CreateOrSet("《=CreatedOnDate", value);
            }
        }
        public DateTime? MinModifiedOnDate
        {
            get
            {
                _Parameter para = GetOrCreate("》=ModifiedOnDate");
                return para.IsNull ? null : (DateTime?)para.GetValue<DateTime>();
            }
            set
            {
                CreateOrSet("》=ModifiedOnDate", value);
            }
        }

        public DateTime? MaxModifiedOnDate
        {
            get
            {
                _Parameter para = GetOrCreate("《=ModifiedOnDate");
                return para.IsNull ? null : (DateTime?)para.GetValue<DateTime>();
            }
            set
            {
                CreateOrSet("《=ModifiedOnDate", value);
            }
        }


        #endregion

        #region 用户
        ///// <summary>
        ///// 创建者
        ///// </summary>
        //public int? CreatedByUserId { get; set; }

        ///// <summary>
        ///// 修改者
        ///// </summary>
        //public int? ModifiedByUserId { get; set; }
        #endregion

        #region 查询

        /// <summary>
        ///指示 当前查询是否需要带出 上级信息
        /// 默认为真
        /// </summary>
        public bool _NeedParentInfo
        {
            get
            {
                _Parameter para = GetOrCreate("_NeedParentInfo");
                if (para.IsNull)
                {
                    para.Value = true;
                }
                return para.BoolenValue;
            }
            set
            {
                CreateOrSet("_NeedParentInfo", value);
            }
        }
        /// <summary>
        ///指示 当前查询是否需要带出 当前对象的JSON信息
        /// </summary>
        public bool _NeedJson
        {
            get
            {
                _Parameter para = GetOrCreate("_NeedJson");
                if (para.IsNull)
                {
                    para.Value = false;
                }
                return para.BoolenValue;
            }
            set
            {
                CreateOrSet("_NeedJson", value);
            }
        }

        /// <summary>
        /// 当前查询的动作
        /// </summary>
        public string _Action
        {
            get
            {
                _Parameter para = GetOrCreate("action");
                if (para.IsNull)
                {
                    para.Value = string.Empty;
                }
                return para.StringValue;
            }
            set
            {
                CreateOrSet("action", value);
            }
        }
        /// <summary>
        /// 当前查询的动作 是否是只读 默认为真
        /// 当返回false时，表示页面可编辑
        /// </summary>
        public bool _IsViewOnly
        {
            get
            {
                return _Action == "view";
            }
            set
            {
                _Action = value ? "view" : "edit";
            }
        }

        /// <summary>
        /// 指示 在返回的数据中 将编码与名称混合作为名称
        /// 默认为假
        /// </summary>
        public bool _ShowNameWithCode
        {
            get
            {
                _Parameter para = GetOrCreate("_ShowNameWithCode");
                if (para.IsNull)
                {
                    para.Value = false;
                }
                return para.BoolenValue;
            }
            set
            {
                CreateOrSet("_ShowNameWithCode", value);
            }
        }
        /// <summary>
        /// 指示 在树状结构的查询中 是否包含自身
        /// parentid={0} or id={0}
        /// 默认为假
        /// </summary>
        public bool _IncludeSelf
        {
            get
            {
                _Parameter para = GetOrCreate("_IncludeSelf");
                if (para.IsNull)
                {
                    para.Value = false;
                }
                return para.BoolenValue;
            }
            set
            {
                CreateOrSet("_IncludeSelf", value);
            }
        }

        /// <summary>
        /// 祖级 Id 用于选择器 页面 确定 根级数据
        /// </summary>
        public _Parameter _Ancient
        {
            get
            {
                _Parameter para = GetOrCreate("_Ancient");
                return para;
            }
        }


        /// <summary>
        /// 祖级 Id 用于选择器 页面 确定 根级数据
        /// </summary>
        public _Parameter _ParentId
        {
            get
            {
                _Parameter para = GetOrCreate("_ParentId");
                return para;
            }
        }

        /// <summary>
        /// 依赖项Id 例如：成本中心 依赖于使用部门
        /// </summary>
        public _Parameter _Dependence
        {
            get
            {
                _Parameter para = GetOrCreate("dependence");
                return para;
            }
        }

        /// <summary>
        /// 保留字段列表，永不为空
        /// </summary>
        public readonly List<string> _ToKeep_Fields = new List<string>();

        public string BuilderSelector()
        {
            return string.Join(",", BuilderSelectorList().Select(x => x.Item1));
        }

        List<Tuple<string, Type>> _BuilderSelectorList = null;
        public List<Tuple<string, Type>> BuilderSelectorList()
        {
            if (_BuilderSelectorList == null)
            {
                if (string.IsNullOrEmpty(_DataViewName))
                    throw new ArgumentNullException("_DataViewName");
                if (HttpContext.Current == null || HttpContext.Current.Request.Path.EndsWith("Export"))
                {

                }
                else
                {
                    if (!string.IsNullOrEmpty(_PrimaryKeyName) && DbHelper.ContainsField(_DataViewName, _PrimaryKeyName))
                        _ToKeep_Fields.Add(_PrimaryKeyName);
                    if (DbHelper.ContainsField(_DataViewName, "Id"))
                        _ToKeep_Fields.Add("Id");
                    if (DbHelper.ContainsField_Code(_DataViewName))
                        _ToKeep_Fields.Add("Code");
                }
                var fields = DbHelper.GetQueryFields(_DataViewName);
                List<Tuple<string, Type>> s = new List<Tuple<string, Type>>();
                foreach (var kv in fields)
                {
                    if (!RegexHelper.IsEnglishOnly(kv.Item1))
                        s.Add(new Tuple<string, Type>(string.Format("[{0}]", kv.Item1), kv.Item2));
                    if (_ToKeep_Fields
                        .Any(x => string.Equals(x, kv.Item1, StringComparison.CurrentCultureIgnoreCase)))
                        s.Add(new Tuple<string, Type>(string.Format("[{0}]", kv.Item1), kv.Item2));
                }
                _BuilderSelectorList = s;
                if (_BuilderSelectorList.Count == 0)
                {
                    _BuilderSelectorList.Add(new Tuple<string, Type>("*", null));
                }
            }
            return _BuilderSelectorList;
        }
        #endregion


        /// <summary>
        /// 无分页的查询语句(非计算属性，即不会自动生成值)
        /// </summary>
        public String QueryString_NoPager
        {
            get
            {
                _Parameter para = GetOrCreate("QueryString_NoPager");
                return para.StringValue;
            }
            set
            {
                CreateOrSet("QueryString_NoPager", value);
            }
        }

        /// <summary>
        /// 判断是否有参数，计算属性
        /// </summary>
        public bool HasParameters
        {
            get
            {
                return _Parameters.Keys.Count(x => !_IsBadParameter.IsMatch(x) && _Parameters[x].IsNotNull) > 0;
            }
            set
            {
                //仅为Xml序列化而留
            }
        }

        /// <summary>
        /// 判断是否存在某个参数，会自动筛选前缀
        /// 如果没有键或值为空，那么返回False
        /// </summary>
        /// <returns></returns>
        public bool HasParameter(string name, bool ignoreCase = false)
        {
            if (string.IsNullOrEmpty(name))
                return false;
            name = _Preview.Replace(name, "");
            return this._Parameters.Any(y => y.Key.EndsWith(name, ignoreCase, Thread.CurrentThread.CurrentCulture)
            && (y.Key.Length <= name.Length + 2)
            && y.Value.IsNotNull);
        }


        /// <summary>
        /// 判断是否存在某个参数，会自动筛选前缀
        /// 如果有键不论值是否为空，那么返回True
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool ContainsKey(string name)
        {
            if (name == null) return false;
            name = _Preview.Replace(name, "");
            return this._Parameters.Any(y => y.Key.EndsWith(name));
        }


        /// <summary>
        /// Lambda表达式树用 检查是否是不良参数的正则表达式
        /// Page开头、dependence、action、dt、纯数字、以_开头 都是不良参数
        /// </summary>
        internal static Regex _IsBadParameter = new Regex(@"^([\d]+|Pager|dependence|action|act|dt|_|im)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        /// <summary>
        /// 拼接查询字符串用 检查是否是不良参数的正则表达式
        /// </summary>
        internal static Regex _IsBadParameter_Builder = new Regex(@"^[\d]+|Pager|action|act|dt|_|ancient|im", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        internal static Regex _Preview = new Regex(@"^《=|《|<=|<|》=|》|>=|>|-|@|!|#", RegexOptions.Compiled);

        internal static char[] _Preview_Tirm = new char[] { '!', '@', '#', '$', '*', '<', '《', '》', '>', '=', '-' };


        /// <summary>
        /// 根据参数创建查询条件
        /// </summary>
        /// <returns></returns>
        public string CreatePredict()
        {
            return DbHelper.CreatePredict(this);
        }

        /// <summary>
        /// 获取排序语句,不包含Order By
        /// </summary>
        /// <returns></returns>
        public string GetOrderBy()
        {
            if (string.IsNullOrEmpty(PagerOrderBy))
            {
                if (string.IsNullOrEmpty(_DataViewName))
                {
                    if (string.IsNullOrEmpty(_PrimaryKeyName))
                    {
                        return " Id Asc";
                    }
                    return string.Format(" {0} Asc", _PrimaryKeyName);
                }
                else if (DbHelper.ContainsField_Order_Weight(_DataViewName))
                {
                    if (DbHelper.ContainsField_ParentId(_DataViewName))
                    {
                        if (DbHelper.ContainsField_Code(_DataViewName))
                        {
                            return "Order_Weight ASC,CODE ASC";
                            //return "LEN(CODE) ASC,Order_Weight ASC,CODE ASC";
                        }
                        else
                        {
                            return "ParentId ASC,Order_Weight ASC";
                        }
                    }
                    else if (DbHelper.ContainsField_Code(_DataViewName))
                    {
                        //if(_Dont_Order_By_Function)
                        return " Order_Weight ASC,CODE ASC";
                        //return " Order_Weight ASC,LEN(CODE) ASC,CODE ASC";
                    }
                    else if (DbHelper.ContainsField_CreatedOnDate(_DataViewName))
                    {
                        return " Order_Weight ASC,CreatedOnDate ASC";
                    }
                    return " Order_Weight ASC";
                }
                else if (DbHelper.ContainsField_Code(_DataViewName))
                {
                    //if(_Dont_Order_By_Function)
                    return "CODE ASC";
                    //return "LEN(CODE) ASC,CODE ASC";
                }
                else if (DbHelper.ContainsField(_DataViewName, "Order_Weight"))
                {
                    return "Order_Weight ASC";
                }
                else
                {
                    if (string.IsNullOrEmpty(_PrimaryKeyName))
                    {
                        return " 1 Asc";
                    }
                    return string.Format(" {0} Asc", _PrimaryKeyName);
                }
            }

            return PagerOrderBy;
        }

        /// <summary>
        /// 获取查询语句 .视图以_v0为名称  0=调用默认的生成查询语句
        /// </summary>
        /// <param name="where">已经有的查询条件，不以And开头</param>
        /// <param name="top">0=调用默认的生成查询语句 1=调用top分页查询的查询语句</param>
        /// <returns></returns>
        public string GetQueryString(string where = null, int top = 0)
        {
            if (string.IsNullOrEmpty(_QueryString))
            {
                return DbHelper.MakeQueryString(this, where, top);
            }
            return _QueryString;
        }

        private string _QueryString = null;
        /// <summary>
        /// 设置查询语句
        /// </summary>
        /// <param name="queryString"></param>
        public void SetQueryString(string queryString)
        {
            _QueryString = queryString;
        }

        /// <summary>
        /// 新增分组
        /// </summary>
        /// <param name="_IsAndRelation">指示新分组内的关系</param>
        [Obsolete("todo:还没有实现")]
        public MyQuery CreateAndAppendNewGroup(bool _IsAndRelation)
        {
            MyQuery child = new MyQuery(_IsAndRelation);
            QueryList.Add(child);
            return child;
        }

        /// <summary>
        /// 动态查询
        /// </summary>
        public virtual IQueryable<TModel> Query<TModel>(IQueryable<TModel> source, Func<IQueryable<TModel>, IOrderedQueryable<TModel>> order)
        {
            Expression<Func<TModel, bool>> func = DbHelper.CreatePredict<TModel>(this, source);
            var query = source.Where(func);
            PagerAllRecordsCount = query.Count();
            if (this.HasPager)
            {
                if (order == null)
                {
                    order = DEFAULT_ORDER;
                }
                var res = order(query)
                     .Skip((int)(PagerIndex * PagerSize)).Take((int)PagerSize);
                return res;
            }
            else
            {
                return query;
            }
        }

        protected virtual IOrderedQueryable<TModel> DEFAULT_ORDER<TModel>(IQueryable<TModel> query)
        {
            Type type = typeof(TModel);
            string orderBy = PagerOrderBy;
            if (string.IsNullOrEmpty(orderBy))
            {
                string pk = null;
                //bool isAsc = false;
                //if (ObjectHelper.IsInheritFrom(type, typeof(IAmsOrderable)))
                //{
                //    pk = "Order_Weight";
                //    //isAsc = true;
                //}
                //else if (ObjectHelper.IsInheritFrom(type, typeof(IAmsEntity)))
                //{
                //    pk = "CreatedOnDate";
                //}
                if (string.IsNullOrEmpty(pk))
                    pk = ObjectHelper.GetPrimaryKeyOrIndexField(type);
                if (pk == null)
                    throw new Exception(string.Format("类型[{0}]没有定义主键", type.FullName));
                orderBy = string.Format("{0} {1}", pk, "ASC");
            }
            return (IOrderedQueryable<TModel>)System.Linq.Dynamic.DynamicQueryable.OrderBy(query, orderBy);

        }

        public virtual IQueryable<TModel> Query<TModel>(IQueryable<TModel> source)
        {
            return Query<TModel>(source, DEFAULT_ORDER);
        }



        #region ICollection

        ICollection<string> IDictionary<string, _Parameter>.Keys
        {
            get
            {
                return _Parameters.Keys;
            }
        }

        ICollection<_Parameter> IDictionary<string, _Parameter>.Values
        {
            get
            {
                return _Parameters.Values;
            }
        }

        int ICollection<KeyValuePair<string, _Parameter>>.Count
        {
            get
            {
                return _Parameters.Count;
            }
        }

        bool ICollection<KeyValuePair<string, _Parameter>>.IsReadOnly
        {
            get
            {
                return false;
            }
        }

        ICollection IDictionary.Keys
        {
            get
            {
                return _Parameters.Keys;
            }
        }

        ICollection IDictionary.Values
        {
            get
            {
                return _Parameters.Values;
            }
        }

        bool IDictionary.IsReadOnly
        {
            get
            {
                return false;
            }
        }

        bool IDictionary.IsFixedSize
        {
            get
            {
                return false;
            }
        }

        int ICollection.Count
        {
            get
            {
                return _Parameters.Count;
            }
        }

        object ICollection.SyncRoot
        {
            get
            {
                return _Parameters._Locker;
            }
        }

        bool ICollection.IsSynchronized
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// 最大执行时间，用于报表，单位秒(s)
        /// </summary>
        public int _MAX_EXECUTE_TIME { get; set; }
        /// <summary>
        /// 指定不要使用Len、SubString等函数作为排序手段
        /// </summary>
        public bool _Dont_Order_By_Function { get; set; }

        object IDictionary.this[object key]
        {
            get
            {
                return _Parameters[key.ToString()].Value;
            }

            set
            {
                _Parameters[key.ToString()].Value = value;
            }
        }

        _Parameter IDictionary<string, _Parameter>.this[string key]
        {
            get
            {
                return _Parameters[key];
            }

            set
            {
                _Parameters[key] = value;
            }
        }


        bool IDictionary<string, _Parameter>.ContainsKey(string key)
        {
            return _Parameters.ContainsKey(key);
        }

        void IDictionary<string, _Parameter>.Add(string key, _Parameter value)
        {
            _Parameters.Add(key, value);
        }

        bool IDictionary<string, _Parameter>.Remove(string key)
        {
            return _Parameters.Remove(key);
        }

        bool IDictionary<string, _Parameter>.TryGetValue(string key, out _Parameter value)
        {
            return _Parameters.TryGetValue(key, out value);
        }

        void ICollection<KeyValuePair<string, _Parameter>>.Add(KeyValuePair<string, _Parameter> item)
        {
            _Parameters.Add(item.Key, item.Value);
        }

        void ICollection<KeyValuePair<string, _Parameter>>.Clear()
        {
            _Parameters.Clear();
        }

        bool ICollection<KeyValuePair<string, _Parameter>>.Contains(KeyValuePair<string, _Parameter> item)
        {
            return _Parameters.Contains(item);
        }

        void ICollection<KeyValuePair<string, _Parameter>>.CopyTo(KeyValuePair<string, _Parameter>[] array, int arrayIndex)
        {
            var i = (ICollection<KeyValuePair<string, _Parameter>>)_Parameters;
            i.CopyTo(array, arrayIndex);
        }

        bool ICollection<KeyValuePair<string, _Parameter>>.Remove(KeyValuePair<string, _Parameter> item)
        {
            var i = (ICollection<KeyValuePair<string, _Parameter>>)_Parameters;
            return i.Remove(item);
        }

        IEnumerator<KeyValuePair<string, _Parameter>> IEnumerable<KeyValuePair<string, _Parameter>>.GetEnumerator()
        {
            return _Parameters.GetEnumerator();
        }

        bool IDictionary.Contains(object key)
        {
            return _Parameters.ContainsKey(key.ToString());
        }

        void IDictionary.Add(object key, object value)
        {
            if (value is _Parameter)
            {
                _Parameter val = value as _Parameter;
                val.Field = key.ToString();
                _Parameters.Add(key.ToString(), val);
            }
            else if (value == null)
            {
                _Parameter val = new _Parameter(string.Empty);
                val.Field = key.ToString();
                _Parameters.Add(key.ToString(), val);
            }
            else
            {
                _Parameter val = new _Parameter(value.ToString());
                val.Field = key.ToString();
                _Parameters.Add(key.ToString(), val);
            }
        }

        void IDictionary.Clear()
        {
            _Parameters.Clear();
        }

        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            return _Parameters.GetEnumerator();
        }

        void IDictionary.Remove(object key)
        {
            _Parameters.Remove(key.ToString());
        }

        void ICollection.CopyTo(Array array, int index)
        {
            _Parameters.ToArray().CopyTo(array, index);
        }

        #endregion

        protected internal readonly List<MyQuery> QueryList = new List<MyQuery>();


    }



    /// <summary>
    /// 查询信息/查询参数集合
    /// 字段使用-前缀，表示模糊匹配 如（-Asset_Name）
    /// 字段以>开头，表示字段值大于参数值
    /// 以此类推，支持大于、大于等于、小于、小于等于
    /// 当存在大小比较就不再作为模糊查找
    /// </summary>

    [Serializable]
    public class MyQuery<TModel>
        : MyQuery
    //where TModel : BaseEntityInfo
    {
        /// <summary>
        /// 以与关系创建查询参数组
        /// </summary>
        public MyQuery() : base() { }

        /// <summary>
        /// 使用自定义关系创建查询参数组
        /// </summary>
        public MyQuery(bool _IsAndRelation) : base(_IsAndRelation) { }



        /// <summary>
        /// 从字符串形式的lamba表达式创建查询
        /// 1.仅支持一个集合的查询
        /// 2.不支持从外界取值,如：x=>x.Name.Contains(_name) 因为使用了变量_name而导致异常
        /// 3.不支持子查询
        /// 4.不支持带语句块的查询:x=>{return x.Name.Contains(_name);}
        /// </summary>
        /// <param name="query">x=>x.Name.Contains("aaa"),将转换成Field:_Name,Value:"aaa"</param>
        /// <returns></returns>
        [Obsolete("", true)]
        public static MyQuery<TModel> Create(string query)
        {
            throw new NotImplementedException();
            //int index= query.IndexOf("=>");
            //if (index <= 0)
            //    throw new ArgumentException("请传入完整的lambda表达式:x=>x.Id==123","query");
            //string go= query.Substring(0, index);
            //go.Remove(go.Length - 3, 2);
            //go = go.Trim();
            //query = query.Substring(index + 2).Trim(' ','\r','\n','\t','{','}');
            //string[] array=query.Split('&')
            //string []  query.Split(';');

        }

    }
}
